package cn.wlinker.video.monitor.brand.hikversion.create.net;

import cn.hutool.core.thread.ThreadUtil;
import cn.wlinker.video.monitor.brand.hikversion.create.net.enums.HCPlayControlEnum;
import cn.wlinker.video.monitor.brand.hikversion.create.net.enums.HCPresetControlEnum;
import cn.wlinker.video.monitor.domain.dto.MonitorDeviceDTO;
import com.sun.jna.ptr.IntByReference;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

/**
 * 云台控制
 *
 * @author gxsjx
 * @version 1.0
 * @date 2022/11/25
 */
@Slf4j
public class HCNetPtzControl {

    private static final HCNetSDK hCNetSDK;

    private int lUserID;//用户句柄

    private int channel;//通道号

    private IntByReference m_err;//错误号

    static {
        hCNetSDK = HCNetTools.hCNetSDK;
    }

    private HCNetPtzControl() {
    }

    public static HCNetPtzControl build(HCNetTools hcNetTools, MonitorDeviceDTO monitorDeviceDTO) {
        return build(hcNetTools.getLUserID(), monitorDeviceDTO.getChannelNo());
    }

    private static HCNetPtzControl build(Integer userID, Integer channelNo) {
        Assert.isTrue(userID != -1, "请先注册");
        HCNetPtzControl hcNetPtzControl = new HCNetPtzControl();
        hcNetPtzControl.lUserID = userID;
        hcNetPtzControl.m_err = new IntByReference(-1);
        hcNetPtzControl.channel = channelNo;
        return hcNetPtzControl;
    }

    void verifyPlayHandle(boolean playHandle) {
        if (!playHandle) {
            hCNetSDK.NET_DVR_GetErrorMsg(m_err);
            if (23 == m_err.getValue()) {
                throw new UnsupportedOperationException(m_err.toString());
            }
            Assert.isTrue(m_err.getValue() != 23, "(开始转动)控制失败!错误原因:" + m_err.getValue() + "," + m_err);
        }
    }

    /**
     * 开始转动
     *
     * @param controlEnum
     * @param mill
     * @return
     */
    @SneakyThrows
    public boolean ptzStart(HCPlayControlEnum controlEnum, int mill) {
        //开始转动
        boolean playHandle = hCNetSDK.NET_DVR_PTZControl_Other(lUserID, channel, controlEnum.getCode(), 0);
        verifyPlayHandle(playHandle);
        ThreadUtil.execute(() -> {
            //控制时间
            try {
                Thread.sleep(mill);
            } catch (InterruptedException e) {
                log.error(e.getMessage(), e);
            }
            //停止控制
            ptzStop(controlEnum);
        });
        return true;
    }

    /**
     * 停止转动
     *
     * @param controlEnum
     * @return
     */
    public boolean ptzStop(HCPlayControlEnum controlEnum) {
        //停止转动
        boolean playHandle = hCNetSDK.NET_DVR_PTZControl_Other(lUserID, channel, controlEnum.getCode(), 1);
        verifyPlayHandle(playHandle);
        return true;
    }

    /**
     * 预置点操作
     *
     * @param index
     * @return
     */
    public Boolean presetControl(HCPresetControlEnum hcPresetControlEnum, int index) {
        boolean playHandle = hCNetSDK.NET_DVR_PTZPreset_Other(lUserID, channel, hcPresetControlEnum.getCode(), index);
        verifyPlayHandle(playHandle);
        return true;
    }
}
